package chapter_3.message.coder;

import chapter_3.message.entity.AbstractMessage;
import chapter_3.message.entity.Candidate;
import chapter_3.message.entity.RequestMessage;
import chapter_3.message.entity.ResponseMessage;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class TextMessageCoder implements MessageCoder {

    public static final int MESSAGE_MAX_LENGTH = 2000;
    private static final String MEGIC_STR = "VOTEPROTO";
    private static final String RESPONSE_STR = "RP";
    private static final String REQUEST_STR = "RQ";
    private static final String INQUIRY_STR = "i";
    private static final String VOTE_STR = "v";
    private static final String DELIMSTR = " ";
    private static final String INQUIRY_VOTENUM_STR = "-1";


    @Override
    public byte[] toWire(AbstractMessage message) {
        StringBuilder messageStr = new StringBuilder("");

        //将消息转换为字符串个数
        //消息字符串格式: "VOTEPROTO"+" "+"[RP|RQ]"+" "+"[i|v]"+" "+candidateId+" "+voteNum
        messageStr.append(MEGIC_STR)
                .append(DELIMSTR)
                .append(message.getResponseFlag() ? RESPONSE_STR : REQUEST_STR)
                .append(DELIMSTR)
                .append(message.getInquiryFlag() ? INQUIRY_STR : VOTE_STR)
                .append(DELIMSTR);
        if (message instanceof RequestMessage) {
            Integer candidateId = ((RequestMessage) message).getCandidateId();
            messageStr.append(candidateId.toString())
                    .append(DELIMSTR)
                    .append(INQUIRY_VOTENUM_STR);
        } else if (message instanceof ResponseMessage) {
            Candidate candidate = ((ResponseMessage) message).getCandidate();
            messageStr.append(Integer.toString(candidate.getId()))
                    .append(DELIMSTR)
                    .append(Integer.toString(candidate.getVoteNumber()));
        }

        byte[] messageData = messageStr.toString().getBytes(StandardCharsets.US_ASCII);
        return messageData;
    }

    @Override
    public AbstractMessage fromWire(byte[] bytes) {
        ByteArrayInputStream messageInputStream = new ByteArrayInputStream(bytes);
        Scanner sc = new Scanner(new InputStreamReader(messageInputStream, StandardCharsets.US_ASCII));

        AbstractMessage message = null;
        boolean responseFlag;
        boolean inquiryFlag;
        int candidateId;
        int candidateVoteNum;
        String token = null;

        //这里用循环+switch语句实现，其实也可以
        try {
            token = sc.next();
            if (!MEGIC_STR.equals(token)) {
                throw new IOException("错误的消息前缀: " + token);
            }
            token = sc.next();
            if (RESPONSE_STR.equals(token)) {
                responseFlag = true;
            } else if (REQUEST_STR.equals(token)) {
                responseFlag = false;
            } else {
                throw new IOException("错误的消息响应字段: " + token);
            }
            token = sc.next();
            if (INQUIRY_STR.equals(token)) {
                inquiryFlag = true;
            } else if (VOTE_STR.equals(token)) {
                inquiryFlag = false;
            } else {
                throw new IOException("错误的消息类型字段: " + token);
            }
            token = sc.next();
            candidateId = Integer.parseInt(token);
            if (responseFlag) {
                token = sc.next();
                candidateVoteNum = Integer.parseInt(token);
                Candidate candidate = new Candidate(candidateId, candidateVoteNum);
                message = new ResponseMessage(inquiryFlag, candidate);
            } else {
                message = new RequestMessage(inquiryFlag, candidateId);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        return message;
    }
}
